001 /*
002 * Copyright 2005 Niclas Hedhman
003 * Copyright 2005 Stephen J. McConnell.
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
014 * implied.
015 *
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019
020 package net.dpml.transit.link;
021
022 import java.io.IOException;
023 import java.io.InputStream;
024 import java.io.OutputStream;
025 import java.net.URI;
026 import java.net.URL;
027 import java.net.URLConnection;
028 import java.security.AccessController;
029 import java.security.PrivilegedExceptionAction;
030 import java.security.PrivilegedActionException;
031 import java.security.PrivilegedAction;
032
033 import net.dpml.transit.Transit;
034 import net.dpml.transit.Artifact;
035 import net.dpml.transit.UnsupportedSchemeException;
036 import net.dpml.util.MimeTypeHandler;
037
038 /**
039 * link: URL protocol connection processor.
040 * @author <a href="http://www.dpml.net">The Digital Product Meta Library</a>
041 * @version 1.0.0
042 */
043 public class LinkURLConnection extends URLConnection
044 {
045 private boolean m_connected;
046 private URL m_targetURL;
047
048 /**
049 * Creation of a new handler.
050 * @param url the url to establish a connection with
051 * @exception NullPointerException if the url argument is null
052 */
053 LinkURLConnection( URL url )
054 throws NullPointerException
055 {
056 super( url );
057 m_connected = false;
058 }
059
060 /**
061 * Establish a connection.
062 *
063 * @exception IOException is an error occurs while attempting to establish
064 * the connection.
065 */
066 public void connect()
067 throws IOException
068 {
069 if( m_connected )
070 {
071 return;
072 }
073
074 m_connected = true;
075
076 try
077 {
078 AccessController.doPrivileged(
079 new PrivilegedExceptionAction()
080 {
081 public Object run()
082 throws IOException
083 {
084 URI linkUri = URI.create( url.toExternalForm() );
085 LinkManager manager = Transit.getInstance().getLinkManager();
086 URI targetUri = manager.getTargetURI( linkUri );
087 if( targetUri != null )
088 {
089 try
090 {
091 Artifact artifact = Artifact.createArtifact( targetUri );
092 m_targetURL = artifact.toURL();
093 }
094 catch( UnsupportedSchemeException use )
095 {
096 m_targetURL = new URL( targetUri.toASCIIString() );
097 }
098 }
099 else
100 {
101 m_targetURL = null;
102 }
103 return null; // nothing to return
104 }
105 }
106 );
107 }
108 catch( PrivilegedActionException e )
109 {
110 throw (IOException) e.getException();
111 }
112 }
113
114 /**
115 * Return an input stream to the resource.
116 * @return the input stream
117 * @exception IOException is an error occurs
118 */
119 public InputStream getInputStream()
120 throws IOException
121 {
122 connect();
123 if( m_targetURL == null )
124 {
125 return null;
126 }
127 else
128 {
129 URLConnection conn = m_targetURL.openConnection();
130 InputStream in = conn.getInputStream();
131 return in;
132 }
133 }
134
135 /**
136 * Return an output stream to the resource.
137 * @return the output stream
138 * @exception IOException if any I/O problems occur.
139 */
140 public OutputStream getOutputStream()
141 throws IOException
142 {
143 connect();
144 if( m_targetURL == null )
145 {
146 return null;
147 }
148 else
149 {
150 URLConnection conn = m_targetURL.openConnection();
151 OutputStream out = conn.getOutputStream();
152 return out;
153 }
154 }
155
156 /**
157 * Reutrn the mimetype of the content.
158 * @return the content mimetype
159 */
160 public String getContentType()
161 {
162 return MimeTypeHandler.getMimeType( "link" );
163 }
164
165 /**
166 * Return the content for this Link.
167 * @param classes a sequence of classes against which the
168 * implementation will attempt to establish a known match
169 * @return the content object (possibly null)
170 * @exception IOException is an error occurs
171 */
172 public Object getContent( final Class[] classes )
173 throws IOException
174 {
175 final LinkManager manager = Transit.getInstance().getLinkManager();
176
177 Object result = AccessController.doPrivileged(
178 new PrivilegedAction()
179 {
180 public Object run()
181 {
182 for( int i=0; i < classes.length; i++ )
183 {
184 Class c = classes[i];
185 if( c.equals( Link.class ) )
186 {
187 String extUri = getURL().toString();
188 URI uri = URI.create( extUri );
189 Link link = new Link( uri, manager );
190 return link;
191 }
192 if( c.equals( URI.class ) )
193 {
194 String extUri = getURL().toString();
195 URI uri = URI.create( extUri );
196 return uri;
197 }
198 }
199 return null;
200 }
201 }
202 );
203
204 if( null != result )
205 {
206 return result;
207 }
208 else
209 {
210 connect();
211 if( null != m_targetURL )
212 {
213 return m_targetURL.getContent( classes );
214 }
215 else
216 {
217 return super.getContent( classes );
218 }
219 }
220 }
221 }